package com.away.fuckingworld.service.impl;

import com.away.fuckingworld.entity.DoubleColorBallHistory;
import com.away.fuckingworld.entity.dto.AppearIntervalTimeCountDTO;
import com.away.fuckingworld.entity.dto.BallAnalyseDTO;
import com.away.fuckingworld.entity.dto.LabelValue;
import com.away.fuckingworld.mapper.DoubleColorBallHistoryMapper;
import com.away.fuckingworld.service.DoubleColorBallService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DoubleColorBallServiceImpl implements DoubleColorBallService {

    private static final String[] BLUES = {
            "01", "02", "03", "04", "05", "06", "07", "08",
            "09", "10", "11", "12", "13", "14", "15", "16"};

    private static final String[] REDS = {
            "01", "02", "03", "04", "05", "06", "07", "08",
            "09", "10", "11", "12", "13", "14", "15", "16",
            "17", "18", "19", "20", "21", "22", "23", "24",
            "25", "26", "27", "28", "29", "30", "31", "32",
            "33"
    };

    @Autowired
    DoubleColorBallHistoryMapper doubleColorBallHistoryMapper;

//    private static final Map<DayOfWeek,Integer>

    /**
     * 获取所有数据
     * @return
     */
    @Override
    public List<DoubleColorBallHistory> listDCBHistory() {
        List<DoubleColorBallHistory> doubleColorBallHistories = doubleColorBallHistoryMapper.selectList(null);
        return doubleColorBallHistories;
    }

    @Override
    public String getLastestCode() {
        QueryWrapper<DoubleColorBallHistory> doubleColorBallHistoryQueryWrapper = new QueryWrapper<>();
        doubleColorBallHistoryQueryWrapper.orderByDesc("code");
        doubleColorBallHistoryQueryWrapper.select("code", "date");
        doubleColorBallHistoryQueryWrapper.last("limit 1");
        DoubleColorBallHistory doubleColorBallHistory = doubleColorBallHistoryMapper.selectOne(doubleColorBallHistoryQueryWrapper);
        String code = "";
        if (Objects.nonNull(doubleColorBallHistory)) {
            code = doubleColorBallHistory.getCode();
            String existDate = doubleColorBallHistory.getDate();
            LocalDate date = LocalDate.parse(existDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            //推断下个开奖时间是否在今年
            DayOfWeek dayOfWeek = date.getDayOfWeek();
            LocalDate nextWrad = LocalDate.now();
            if (dayOfWeek.equals(DayOfWeek.TUESDAY)) {
                nextWrad = date.with(TemporalAdjusters.next(DayOfWeek.THURSDAY));
            } else if (dayOfWeek.equals(DayOfWeek.THURSDAY)) {
                nextWrad = date.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
            } else if (dayOfWeek.equals(DayOfWeek.SUNDAY)) {
                nextWrad = date.with(TemporalAdjusters.next(DayOfWeek.TUESDAY));
            }
            if (nextWrad.getYear() - date.getYear() > 0) {
                code = nextWrad.getYear() + "001";
            }

        }
        return code;
    }


    @Override
    @Transactional
    public void saveDoubleColorBallHistorys(List<DoubleColorBallHistory> doubleColorBallHistoryList) {
        for (DoubleColorBallHistory doubleColorBallHistory : doubleColorBallHistoryList) {
            saveDoubleColorBallHistory(doubleColorBallHistory);
        }
    }


    @Override
    @Transactional
    public void saveDoubleColorBallHistory(DoubleColorBallHistory doubleColorBallHistory) {
        QueryWrapper<DoubleColorBallHistory> doubleColorBallHistoryQueryWrapper = new QueryWrapper<>();
        doubleColorBallHistoryQueryWrapper.lambda().eq(DoubleColorBallHistory::getCode, doubleColorBallHistory.getCode());
        DoubleColorBallHistory oldData = doubleColorBallHistoryMapper.selectOne(doubleColorBallHistoryQueryWrapper);
        if (Objects.isNull(oldData)) {
            doubleColorBallHistoryMapper.insert(doubleColorBallHistory);
        }
    }

    @Override
    public List<BallAnalyseDTO> blueInfoOrder() {
        List<BallAnalyseDTO> ballAnalyseDTOS = blueInfo();
        List<BallAnalyseDTO> ballAnalyseDescDTOS =ballAnalyseDTOS.stream().sorted(Comparator.comparing(BallAnalyseDTO::getNDisAppear).reversed()).collect(Collectors.toList());
       log.debug("篮球号" + "\t" + "最长n期未出现" + "\t" + "已经n期未出现" + "\t" + "一共出现了次数" + "\t"+ "超过n期未出现的次数"+ "\t"+ "超过25期未出现的次数" + "\t" + "超过50期未出现的次数");

        ballAnalyseDescDTOS.forEach(
                t->{
                    log.debug(t.getBallNum() + "\t" + t.getMaxInterval() + "\t" + t.getNDisAppear() + "\t" + t.getTotalAppear() + "\t" + t.getMoreThanNDisAppear() + "\t" + t.getMoreThanN1DisAppear() + "\t" + t.getMoreThanN2DisAppear());

                }
        );
        return ballAnalyseDescDTOS;
    }

    private List<BallAnalyseDTO> blueInfo(){
        List<BallAnalyseDTO> result = new ArrayList<>();
        log.debug("篮球号" + "\t" + "最长n期未出现" + "\t" + "已经n期未出现" + "\t" + "一共出现了次数" + "\t" + "50期未出现的次数");
        for (String blue : BLUES) {
            Long lastest = lastestBlue(blue);
            Long maxInterval = maxIntervalBlue(blue);
            Long total = totalBlue(blue);
            Long n = intervalTimesBlue(blue, lastest);
            Long moreThan25 = intervalTimesBlue(blue, 25L);
            Long moreThan50 = intervalTimesBlue(blue, 50L);
            log.debug(blue + "\t" + maxInterval + "\t" + lastest + "\t" + total + "\t" + moreThan50);
            BallAnalyseDTO ballAnalyseDTO = new BallAnalyseDTO(blue,maxInterval,lastest,total,n,moreThan25,moreThan50);
            result.add(ballAnalyseDTO);
        }
        return result;
    }

    @Override
    public List<BallAnalyseDTO> redInfoOrder() {
        List<BallAnalyseDTO> ballAnalyseDTOS = redInfo();

        List<BallAnalyseDTO> ballAnalyseDescDTOS =ballAnalyseDTOS.stream().sorted(Comparator.comparing(BallAnalyseDTO::getNDisAppear).reversed()).collect(Collectors.toList());
        log.debug("红球号" + "\t" + "最长n期未出现" + "\t" + "已经n期未出现" + "\t" + "一共出现了次数" + "\t"+ "超过n期未出现的次数"+ "\t"+ "超过10期未出现的次数" + "\t" + "超过20期未出现的次数");
        ballAnalyseDescDTOS.forEach(
                t->{
                    log.debug(t.getBallNum() + "\t" + t.getMaxInterval() + "\t" + t.getNDisAppear() + "\t" + t.getTotalAppear() + "\t" + t.getMoreThanNDisAppear() + "\t" + t.getMoreThanN1DisAppear() + "\t" + t.getMoreThanN2DisAppear());

                }
        );
        return ballAnalyseDescDTOS;
    }

    public List<BallAnalyseDTO>  redInfo(){
        List<BallAnalyseDTO> result = new ArrayList<>();
        log.debug("红球号" + "\t" + "最长n期未出现" + "\t" + "已经n期未出现" + "\t" + "一共出现了次数" + "\t" + "20期未出现的次数");
        for (String red : REDS) {
            Long lastest = lastestRed(red);
            Long maxInterval = maxIntervalRed(red);
            Long total = totalRed(red);
            Long n = intervalTimesRed(red, lastest);
            Long moreThan10 = intervalTimesRed(red, 10L);
            Long moreThan20 = intervalTimesRed(red, 20L);
            log.debug(red + "\t" + maxInterval + "\t" + lastest + "\t" + total + "\t" + moreThan20);
            BallAnalyseDTO ballAnalyseDTO = new BallAnalyseDTO(red,maxInterval,lastest,total,n,moreThan10,moreThan20);
            result.add(ballAnalyseDTO);
        }
        return result;
    }

    @Override
    public List<LabelValue> lastestBlueInfo() {
        List<LabelValue> result = new ArrayList<>();
        for (String blue : BLUES) {
            Long maxInterval = lastestBlue(blue);
            result.add(new LabelValue(blue, maxInterval));
        }
        return result;
    }

    @Override
    public List<LabelValue> maxIntervalBlueInfo() {
        List<LabelValue> result = new ArrayList<>();
        for (String blue : BLUES) {
            Long maxInterval = maxIntervalBlue(blue);
            result.add(new LabelValue(blue, maxInterval));
        }
        return result;
    }

    /**
     * 蓝球出现的最大间隔时间
     *
     * @param num
     */
    public Long maxIntervalBlue(String num) {
        List<DoubleColorBallHistory> doubleColorBallHistories = doubleColorBallHistoryMapper.selectList(Wrappers.lambdaQuery(DoubleColorBallHistory.builder().ball7(num).build()).orderBy(true, true, DoubleColorBallHistory::getCode).select(DoubleColorBallHistory::getId));
        DoubleColorBallHistory tmp = null;
        Long max = -1L;
        for (DoubleColorBallHistory doubleColorBallHistory : doubleColorBallHistories) {
            if (Objects.isNull(tmp)) {
                tmp = doubleColorBallHistory;
                continue;
            }
            Long tmpMax = doubleColorBallHistory.getId() - tmp.getId();
            max = max < tmpMax ? tmpMax : max;
            tmp = doubleColorBallHistory;
        }
        return max;
    }


    /**
     * 红球出现的最大间隔时间
     *
     * @param num
     */
    public Long maxIntervalRed(String num) {
        List<DoubleColorBallHistory> doubleColorBallHistories = doubleColorBallHistoryMapper.selectList(
                Wrappers.lambdaQuery(new DoubleColorBallHistory())
                        .eq(DoubleColorBallHistory::getBall1, num)
                        .or().eq(DoubleColorBallHistory::getBall2, num)
                        .or().eq(DoubleColorBallHistory::getBall3, num)
                        .or().eq(DoubleColorBallHistory::getBall4, num)
                        .or().eq(DoubleColorBallHistory::getBall5, num)
                        .or().eq(DoubleColorBallHistory::getBall6, num)
                        .orderBy(true, true, DoubleColorBallHistory::getCode).select(DoubleColorBallHistory::getId));
        DoubleColorBallHistory tmp = null;
        Long max = -1L;
        for (DoubleColorBallHistory doubleColorBallHistory : doubleColorBallHistories) {
            if (Objects.isNull(tmp)) {
                tmp = doubleColorBallHistory;
                continue;
            }
            Long tmpMax = doubleColorBallHistory.getId() - tmp.getId();
            max = max < tmpMax ? tmpMax : max;
            tmp = doubleColorBallHistory;
        }
        return max;
    }


    /**
     * 蓝球最近一次出现距离本次的期数差
     *
     * @param num
     * @return
     */
    public Long lastestBlue(String num) {
        //最近一次出现的id
        DoubleColorBallHistory lastAppear = doubleColorBallHistoryMapper.selectOne(Wrappers.lambdaQuery(DoubleColorBallHistory.builder().ball7(num).build()).orderBy(true, false, DoubleColorBallHistory::getCode).last("limit 1").select(DoubleColorBallHistory::getId));
        //上一个开奖日期的id
        DoubleColorBallHistory lastward = doubleColorBallHistoryMapper.selectOne(Wrappers.lambdaQuery(new DoubleColorBallHistory()).orderBy(true, false, DoubleColorBallHistory::getCode).last("limit 1").select(DoubleColorBallHistory::getId));
        return lastward.getId() - lastAppear.getId();
    }

    /**
     * 红球最近一次出现距离本次的期数差
     *
     * @param num
     * @return
     */
    public Long lastestRed(String num) {
        //最近一次出现的id
        DoubleColorBallHistory lastAppear = doubleColorBallHistoryMapper.selectOne(
                Wrappers.lambdaQuery(new DoubleColorBallHistory())
                        .eq(DoubleColorBallHistory::getBall1, num)
                        .or().eq(DoubleColorBallHistory::getBall2, num)
                        .or().eq(DoubleColorBallHistory::getBall3, num)
                        .or().eq(DoubleColorBallHistory::getBall4, num)
                        .or().eq(DoubleColorBallHistory::getBall5, num)
                        .or().eq(DoubleColorBallHistory::getBall6, num)
                        .orderBy(true, false, DoubleColorBallHistory::getCode).last("limit 1").select(DoubleColorBallHistory::getId));
        //上一个开奖日期的id
        DoubleColorBallHistory lastward = doubleColorBallHistoryMapper.selectOne(Wrappers.lambdaQuery(new DoubleColorBallHistory()).orderBy(true, false, DoubleColorBallHistory::getCode).last("limit 1").select(DoubleColorBallHistory::getId));
        return lastward.getId() - lastAppear.getId();
    }


    /**
     * 该数字篮球一共出现的次数
     *
     * @param num
     * @return
     */
    public Long totalBlue(String num) {
        Integer total = doubleColorBallHistoryMapper.selectCount(Wrappers.lambdaQuery(DoubleColorBallHistory.builder().ball7(num).build()));
        return total.longValue();
    }

    /**
     * 该数字篮球一共出现的次数
     *
     * @param num
     * @return
     */
    public Long totalRed(String num) {
        Integer total = doubleColorBallHistoryMapper.selectCount(
                Wrappers.lambdaQuery(new DoubleColorBallHistory())
                        .eq(DoubleColorBallHistory::getBall1, num)
                        .or().eq(DoubleColorBallHistory::getBall2, num)
                        .or().eq(DoubleColorBallHistory::getBall3, num)
                        .or().eq(DoubleColorBallHistory::getBall4, num)
                        .or().eq(DoubleColorBallHistory::getBall5, num)
                        .or().eq(DoubleColorBallHistory::getBall6, num)
        );
        return total.longValue();
    }

    /**
     * 蓝球出现期数间隔超过times的数量
     *
     * @param num
     * @param times
     */
    public Long intervalTimesBlue(String num, Long times) {
        List<DoubleColorBallHistory> doubleColorBallHistories = doubleColorBallHistoryMapper.selectList(Wrappers.lambdaQuery(DoubleColorBallHistory.builder().ball7(num).build()).orderBy(true, true, DoubleColorBallHistory::getCode).select(DoubleColorBallHistory::getId));
        DoubleColorBallHistory tmp = null;
        Long total = 0L;
        for (DoubleColorBallHistory doubleColorBallHistory : doubleColorBallHistories) {
            if (Objects.isNull(tmp)) {
                tmp = doubleColorBallHistory;
                continue;
            }
            if (doubleColorBallHistory.getId() - tmp.getId() > times) {
                total++;
            }
            tmp = doubleColorBallHistory;
        }
        return total++;
    }

    /**
     * 红球出现期数间隔超过times的数量
     *
     * @param num
     * @param times
     */
    public Long intervalTimesRed(String num, Long times) {
        List<DoubleColorBallHistory> doubleColorBallHistories = doubleColorBallHistoryMapper.selectList(
                Wrappers.lambdaQuery(new DoubleColorBallHistory())
                        .eq(DoubleColorBallHistory::getBall1, num)
                        .or().eq(DoubleColorBallHistory::getBall2, num)
                        .or().eq(DoubleColorBallHistory::getBall3, num)
                        .or().eq(DoubleColorBallHistory::getBall4, num)
                        .or().eq(DoubleColorBallHistory::getBall5, num)
                        .or().eq(DoubleColorBallHistory::getBall6, num)
                        .orderBy(true, true, DoubleColorBallHistory::getCode).select(DoubleColorBallHistory::getId));
        DoubleColorBallHistory tmp = null;
        Long total = 0L;
        for (DoubleColorBallHistory doubleColorBallHistory : doubleColorBallHistories) {
            if (Objects.isNull(tmp)) {
                tmp = doubleColorBallHistory;
                continue;
            }
            if (doubleColorBallHistory.getId() - tmp.getId() > times) {
                total++;
            }
            tmp = doubleColorBallHistory;
        }
        return total++;
    }


    @Override
    public List<AppearIntervalTimeCountDTO> blueAppearIntervalTimeCount(){
        List<AppearIntervalTimeCountDTO> result = new ArrayList<>();
        for (String blue : BLUES) {
            List<AppearIntervalTimeCountDTO> appearIntervalTimeCountDTOS = doubleColorBallHistoryMapper.appearIntervalTimeCount(blue);
            result.addAll(appearIntervalTimeCountDTOS);
        }
        log.debug(String.valueOf(result));
        return result;
    }


}
